<?php
//------------------------
// 前台搜索页面控制器
//-------------------------

namespace app\home\controller;

use app\common\controller\HomeBase;
use app\common\model\GoodsCate as GoodsCateModel;
use app\common\model\Goods as GoodsModel;
use think\Cache;


class Search extends HomeBase
{
    protected $GoodsCateModel;
    protected $GoodsModel;

	protected function _initialize()
    {
        parent::_initialize();
        $this->GoodsCateModel              = new GoodsCateModel();
        $this->GoodsModel                  = new GoodsModel();
    }



    public function index(){
        $cate_id = $this->request->param('cate_id',0,'intval');
        $brand_id = $this->request->param('brand_id','','trim');//为了传入all，所以不用intval
        $search_price = $this->request->param('search_price','','trim');
        $search_attr = input('param.search_attr','','trim'); // 属性搜索字符串

        $sort = $this->request->param('sort','','trim');

        $searchData = $this->request->param('searchData','','trim');//搜索与排序数据序列化

        $_searchData = my_unserialize($searchData);

        if ( !empty($_searchData['where']['cate_id']) ) {
            $cate_id = $_searchData['where']['cate_id'][1][0];
        }

        if (!$brand_id && !empty($_searchData['where']['brand_id']) ) {
            $brand_id = $_searchData['where']['brand_id'][1];
        }

        if (!$search_price && !empty($_searchData['where']['now_price']) ) {
            $search_price = implode('-',$_searchData['where']['now_price'][1]);
        }

        if (!$search_attr && !empty($_searchData['where']['id']) ) {
            $search_attr = $_searchData['search_attr'];
        }

        if (!$sort && !empty($_searchData['sort']) ) {
            $sort = $_searchData['sort'];
        }

        $GoodsModle = Db('Goods');

        /********************* 可以搜索的分类品牌 *****************************/
        // 先从缓存中查看是否存在这个分类的搜索结果
        $brandData = Cache::get('brand_' . $cate_id);

        if (!$brandData) {
            $brandData = array();
            $GoodsBrandModel = Db('GoodsBrand');
            // 取出当前分类下面有商品的品牌
            $brandKey = $GoodsModle->distinct(true)->field('brand_id')->where('cate_id',$cate_id)->select()->toArray();

            $brandKey = two_to_one($brandKey,'brand_id');

            // 循环所有的筛选品牌，取出这些品牌中有商品的值
            foreach ($brandKey as $v){
                $brandData[] = $GoodsBrandModel->field('id,brand_name,brand_logo')->where('id',$v)->find();
            }

            // 将结果存到缓存中
            Cache::set('brand_' . $cate_id,$brandData,3600);
        }

        $this->assign('brandData',$brandData);

        /********************* 计算这个分类下商品的七个价格区间的范围 *****************************/
        // 先从缓存中查看是否存在这个分类的搜索结果
        $priceData = Cache::get('price_' . $cate_id);

        if (!$priceData) {
            $priceSection = 7; // 要分的段数
            // 算法：取出这个分类下商品的最低价和最高价
            $price = $GoodsModle->field('MIN(now_price) min_price,MAX(now_price) max_price')->where('cate_id',$cate_id)->find();

            // 最低价和最高价分七段
            $priceData = array();
            // // 计算每个段应该价格区间
            $sprice = ($price['max_price'] - $price['min_price']) / $priceSection;
            $firstPrice = $price['min_price'];
            for($i = 0; $i < $priceSection; $i++) {
                if($i < ($priceSection - 1)){
                    $start = floor($firstPrice/10)*10;
                    $end = (floor(($firstPrice+$sprice)/10)*10-1);
                    // 先判断这个分类下在这个价格段中是否有商品
                    $goodsCount = $GoodsModle
                        ->where('cate_id',$cate_id)
                        ->where('status',1)
                        ->where('now_price','between',array($start, $end))
                        ->count();
                    $firstPrice += $sprice;

                    if($goodsCount == 0){
                        continue;
                    }
                    $priceData[] = $start . '-'. $end;

                } else {
                    $start = floor($firstPrice/10)*10;
                    $end = ceil($price['max_price']/10)*10;
                    // 先判断这个分类下在这个价格段中是否有商品
                    $goodsCount = $GoodsModle
                        ->where('cate_id',$cate_id)
                        ->where('status',1)
                        ->where('now_price','between',array($start, $end))
                        ->count();
                    $firstPrice+=$sprice;
                    if($goodsCount == 0){
                        continue;
                    }
                    $priceData[] = floor($firstPrice/10)*10 . '-'. ceil($price['max_price']/10)*10;
                }
            }

            // 将结果存到缓存中
            Cache::set('price_' . $cate_id,$priceData,3600);
        }

        $this->assign('priceData',$priceData);

        /********************* 可以搜索的属性 *****************************/
        // 先从缓存中查看是否存在这个分类的搜索结果
        $attrData = Cache::get('attr_data_' . $cate_id);
        // $attrData = array();

        if (!$attrData) {
            $attrKey = Db('GoodsCate')->field('attr_key')->find($cate_id);
            // 根据筛选属性的ID取出这些属性的名称以及每个属性所拥有的值
            $attrData = Db('TypeAttr')->field('id,attr_name')->where('id','in',$attrKey['attr_key'])->where('search_index',1)->select()->toArray();
            // 循环所有的筛选属性，取出这些属性中有商品的值
            $goodsAttrModel = Db('GoodsAttr');
            foreach ($attrData as $k => $v){
                // 找出这个属性有商品的值  --> 从商品属性表(一件商品所拥有的属性以及值）
                $attrValues = $goodsAttrModel->field('DISTINCT value')->where('attr_id',$v['id'])->select()->toArray();
                // 如果这个属性下没有商品,那么就删除这个属性
                if(!$attrValues){
                    unset($attrData[$k]);
                } else {
                    $attrData[$k]['attr_value'] = $attrValues;
                }
            }

            // 将结果存到缓存中
            Cache::set('attr_data_' . $cate_id,$attrData,3600);
        }

        $this->assign('attrData',$attrData);

        $attrCount = count($attrData);

        if ($search_attr) {
            $_attr_arr = explode('.', $search_attr);
        } else {
            $_attr_arr = array_fill(0, $attrCount, 'all');
        }

        $this->assign('_attr_arr',$_attr_arr);

        /***************************************商品*******************************/
        $where = $_searchData['where'];

        // 上架状态
        $where['status'] = array('eq',1);

        // 分类id
        if ($cate_id) {
            $cateArray = $this->GoodsCateModel->getChildren($cate_id);
            array_unshift($cateArray,(int)$cate_id);// 将原分类id插入到数组的开头
            $where['cate_id'] = array('in',$cateArray);
        }

        // 品牌id
        if ($brand_id && $brand_id != 'all') {
            $where['brand_id'] = array('eq',$brand_id);
        } elseif ($brand_id && $brand_id == 'all') {
            unset($where['brand_id']);
        }

        // 价格区间
        if ($search_price && $search_price != 'all') {
            $_search_price = explode('-', $search_price);
            $where['now_price'] = array('between',$_search_price);
        } elseif ($search_price && $search_price == 'all') {
             unset($where['now_price']);
        }

        // 属性
        if ( $search_attr ) {
            $goodsAttrModel = Db('GoodsAttr');
            $search_attr_arr = explode('.', $search_attr);

            // 属性搜索基础状态为假
            $search_attr_status = false;

            // 如果其中有不为all的，status就为真
            foreach ($search_attr_arr as $k => $v) {
                if ($v != 'all') {
                    $search_attr_status = true;
                }
            }

            if ($search_attr_status) {
                // 商品id集合
                $goods_id_array = null;
                // 现在要找出满足所有的条件的商品ID字符串取交集
                foreach ($search_attr_arr as $k => $v) {
                    if ( $v != 'all' ) {
                        $_v = explode('-', $v);
                        // 到商品属性表中搜索有这个属性以及值的商品的ID,并返回字符串1,2,3,4
                        $attrGoodsId = $goodsAttrModel->field('GROUP_CONCAT(goods_id) goods_id')
                        ->where('attr_id',$_v[1])
                        ->where('value',$_v[0])
                        ->find();

                        if ($goods_id_array === null) {
                            $goods_id_array = explode(',', $attrGoodsId['goods_id']);
                        } else {
                            // 如果$_attr1不为空，保存的就是上一次满足条件的商品ID,那么就和这次取交集
                            $_attrGoodsId = explode(',', $attrGoodsId['goods_id']);
                            $goods_id_array = array_intersect($goods_id_array, $_attrGoodsId);
                            // 如果已经是空了就直接退出不用再比较了，肯定没交集
                            if( empty($goods_id_array) ){
                                break;
                            }
                        }
                    }
                }

                if ( $goods_id_array ) {
                    $where['id'] = array('in', $goods_id_array);
                } else {
                    $where['id'] = array('eq', 0);  
                }
            } else {
                unset($where['id']);
            }
        }

        // 将搜索与排序条件序列化后传到页面中
        $Data['where'] = $where;
        $Data['search_attr'] = $search_attr;
        $Data['sort'] = $sort;
        $searchData = my_serialize($Data);

        $_sort = '';
        if ($sort) {
            $_sort = str_replace('_d',' desc',$sort);
        }

        $goodsInfo = $this->GoodsModel->where($where)->order($_sort)->
          paginate(6,false,['query' => ['searchData' => $searchData] ]);

        $this->assign('search_price',$search_price);//价格区间
        $this->assign('brand_id',$brand_id);//品牌id
        $this->assign('sort',$sort);//排序方式

        $this->assign('searchData',$searchData);
        $this->assign('goodsInfo',$goodsInfo);

        return $this->fetch('index');
    }

}
